#define _gam_cmd_included 1

#if !defined _gam_stock_included
	#include <gam\stock>
#endif

#if !defined _gam_wpn_req_included
	#include <gam\wpn_req>
#endif

#if defined USE_SQL
	#include <sqlx>
#else
	#if !defined _gam_nvault_included
		#include <gam\nvault>
	#endif
#endif


//{ ADMIN COMMANDS
public loadLevels(id, level, cid) {
	if(cmd_access(id, level, cid, 0)){
		doLoadLevels();
	}
}
public setLevel(id, level, cid){
	if(!isActive())
		return PLUGIN_CONTINUE;
		
	if(!cmd_access(id,level,cid, 0)) // user has no access to command
		return PLUGIN_HANDLED;
	
	new bool:printParams = false;
	if(!cmd_access(id,level,cid, 3)) //if no access - user has access but not all params are specified
		printParams = true;
		
	new nick[MAX_KEY_LEN];
	new sWeapon[2];
	new sLevel[2];
	read_argv(1, nick, MAX_KEY_LEN-1);
	read_argv(2, sWeapon, 2);
	read_argv(3, sLevel, 1);
	new weapon;
	new level;
	if(is_str_num(sWeapon) && is_str_num(sLevel)) {
		weapon = str_to_num(sWeapon);
		level = str_to_num(sLevel);
		if(isLevelWeapon(weapon) && LEVEL_NONE<level<WEAPONS_LEVELS) {
			new player = cmd_target(id, nick, CMDTARGET_ALLOW_SELF);
			if(player){
				setClientWeaponLevel(player, weapon, level);
				return PLUGIN_HANDLED;
			}
		} else {
			client_print(id, print_console, "%L", id, "WEAPON_ID");
			printParams = true;
		}
	} else {
		printParams =true;
	}
	if(printParams){
		new name[32];
		for(weapon = 1;weapon<WEAPONS;weapon++){
			if(isLevelWeapon(weapon)){
				getWeaponName4Level(id, weapon, name, 31);
				client_print(id, print_console, "%d - %s", weapon, name);
			}
		}
		client_print(id, print_console, "%L", id, "LEVELS");
		for(weapon=LEVEL_BEGINNER;weapon<WEAPONS_LEVELS; weapon++){
			getLevelName(id, weapon, name, 31);
			client_print(id, print_console, "%d - %s", weapon, name);
		}
	}
	return PLUGIN_HANDLED;
}
//}
//{ OTHER COMMANDS
public showHud(id){
	if(!isActive()) return PLUGIN_CONTINUE;
	if(!task_exists(id+TASK_DISPLAY_RANK))
		displayIfno(id, 8.0);
	return PLUGIN_HANDLED;
}
public buyHe(id){
	if(!isActive())
		return PLUGIN_CONTINUE;
	if(!isLevelPowers())
		return PLUGIN_CONTINUE;
	if(!is_user_alive(id))
		return PLUGIN_CONTINUE;
	new lvl = gPlayerLevelInfo[id][WEAPONS_HEGRENADE];
	new ammo = cs_get_user_bpammo(id , WEAPONS_HEGRENADE);
	if(!ammo || ammo > 1)
		return PLUGIN_CONTINUE;
	if(!cs_get_user_buyzone(id)){
		return PLUGIN_CONTINUE;
	}
	if(!isBuyTime()){
		return PLUGIN_CONTINUE;
	}
	
	if(lvl == LEVEL_VETERAN) {
		new money = cs_get_user_money(id);
		if(money >= 300) {
			cs_set_user_money(id, money - 300, 1);
			cs_set_user_bpammo(id , WEAPONS_HEGRENADE , 2);
			return PLUGIN_HANDLED;
		}
	}
	return PLUGIN_CONTINUE;
}
public showCurWpnReq(id){
	if(!isActive())
		return PLUGIN_CONTINUE;
	if(is_user_alive(id)){
		new wpn = get_user_weapon(id);
		showWeaponReq(id, wpn);
	} else {
		client_print(id, print_chat, "%L", id, "CMD_FOR_ALIVE");
	}
	return PLUGIN_HANDLED;
}

public savePlayer(id) {
	if(!isActive())
		return PLUGIN_CONTINUE;
	if(gPlayerSaveNeeded[id]){	
		if(isPlayerAuthorized(id)){
			savePlayerWpnStats(id);
			ColorChat(id, RED, "%L", id, "DATA_SAVED");
		} else {
			ColorChat(id, RED, "%L", id, "NOT_AUTHORIZED");
		}
	}
	return PLUGIN_HANDLED;
}
//}
//{ STOCK
stock doLoadLevels(){
	new cfg[128];
	new Text[64];
	
	get_configsdir(cfg, charsmax(cfg));
	format(cfg, charsmax(cfg),"%s/gam_wpn_levels.ini");
	new players[32];
	new num;
	new player;
	get_players(players, num, "ch");
	new i;
	if(file_exists(cfg)){
		new File = fopen(cfg, "r");
		if(File){
			new nick[36];
			new swpn[4];
			new slevel[4];
			new level, wpn;
			new bool:clientSet;
			while (!feof(File)){
				fgets(File,Text,charsmax(Text));
				trim(Text);
				if (Text[0]==';' || Text[0] ==0) 
					continue;
				parse(Text, nick, charsmax(nick), swpn, charsmax(swpn), slevel, charsmax(slevel));
				remove_quotes(nick);
				remove_quotes(slevel);
				remove_quotes(swpn);
				
				wpn = str_to_num(swpn);
				level = str_to_num(slevel);
				if(isLevelWeapon(wpn) && LEVEL_NONE<level<WEAPONS_LEVELS){
					clientSet = false;
					for(i=0;i<num;i++){
						player = players[i];
						if(equali(gPlayerKey[player], nick)){
							if(gPlayerLevelInfo[player][wpn] < level){
								setClientWeaponLevel(player, wpn, level);
								clientSet=true;
								savePlayerWpnStats(player);
								break;
							}
						}
					}
					if(!clientSet){
						copy(gPlayerKey[0], MAX_KEY_LEN-1, nick);
						readPlayerSettings(0);
						if(gPlayerLevelInfo[0][wpn] < level){
							setClientWeaponLevel(0, wpn, level);
							savePlayerWpnStats(0);
						}
					}
				}
			}
		}
	}
}

stock showLngMotd(id, const lngMotdFile[]){
	new motd[128];	
	formatex(motd, charsmax(motd), "%L", id, lngMotdFile);	
	show_motd(id, motd, PLUGIN);
}
stock showWeaponGroupMenu(id, const menuTitleLng[], const handler[]){
	new title[64];
	formatex(title, charsmax(title), "\r%L",id,  menuTitleLng);
	new menu = menu_create(title, handler);
	new info[2];
	
	info[1] = GROUP_PISTOLS;
	formatex(title, charsmax(title), "%L", id, "GROUP_PISTOLS");
	menu_additem(menu, title, info);
	
	info[1] = GROUP_SMG;
	formatex(title, charsmax(title), "%L", id, "GROUP_SMG");
	menu_additem(menu, title, info);
	
	info[1] = GROUP_SHOTGUNS;
	formatex(title, charsmax(title), "%L", id, "GROUP_SHOTGUNS");
	menu_additem(menu, title, info);
	
	info[1] = GROUP_RIFELS;
	formatex(title, charsmax(title), "%L", id, "GROUP_RIFELS");
	menu_additem(menu, title, info);
	
	info[1] = GROUP_SNIPERS;
	formatex(title, charsmax(title), "%L", id, "GROUP_SNIPERS");
	menu_additem(menu, title, info);
	
	info[1] = GROUP_EXPLODE;
	formatex(title, charsmax(title), "%L", id, "GROUP_EXPLODE");
	menu_additem(menu, title, info);
	
	info[1] = GROUP_KNIFE;
	formatex(title, charsmax(title), "%L", id, "GROUP_KNIFE");
	menu_additem(menu, title, info);
	
	info[1] = GROUP_PARA;
	formatex(title, charsmax(title), "%L", id, "GROUP_PARA");
	menu_additem(menu, title, info);
	
	menu_display(id, menu);
	return PLUGIN_HANDLED;
}

//}

//{ MAIN MENU
enum _:MAIN_MENU_ITEMS{
	MI_NONE,
	MI_COMMANDS,
	MI_WPN_LVL_REQ,
	MI_WPN_LVL_BENEFITS,	
	MI_SETTINGS
}
public showMenu(id){
	new title[64];
	formatex(title, charsmax(title), "\r%s", PLUGIN);
	new menu = menu_create(title, "mainMenuHandler");
	new info[2];
	
	info[0] = MI_COMMANDS;
	formatex(title, charsmax(title), "%L", id, "MI_COMMANDS");
	menu_additem(menu, title,info);
	
	info[0] = MI_WPN_LVL_REQ;
	formatex(title, charsmax(title), "%L", id, "MI_WPN_LVL_REQ");
	menu_additem(menu, title,info);
	
	info[0] = MI_WPN_LVL_BENEFITS;
	formatex(title, charsmax(title), "%L", id, "MI_WPN_LVL_BENEFITS");
	menu_additem(menu, title,info);
	
	info[0] = MI_SETTINGS;
	formatex(title, charsmax(title), "%L", id, "MI_SETTINGS");
	menu_additem(menu, title,info);
	
	menu_display(id, menu);
	return PLUGIN_HANDLED;
}

public mainMenuHandler(id, menu, item){
	if(item == MENU_EXIT){
		menu_destroy(menu);
		return PLUGIN_HANDLED;
	}
	new acc, call;
	new info[2];
	menu_item_getinfo(menu, item, acc, info, 1, _, _, call);
	switch(info[0]){
		case MI_COMMANDS: showCommands(id);
		case MI_WPN_LVL_REQ: showLevelReqMenu(id);
		case MI_WPN_LVL_BENEFITS: showLevelBenefitsMenu(id);
		case MI_SETTINGS: showSettingsMenu(id);
		
	}
	menu_destroy(menu);
	return PLUGIN_HANDLED;
}

//} MAIN MENU
//{ COMMANDS
public  showCommands(id){
	if(!isActive())
		return PLUGIN_CONTINUE;
	showLngMotd(id, "MOTD_COMMANDS");
	return PLUGIN_HANDLED;
}

//}
//{ WEAPON ELVEL REQ
public showLevelReqMenu(id){
	showWeaponGroupMenu(id, "MI_WPN_LVL_REQ", "levelReqHandler");
	return PLUGIN_HANDLED;
}
public levelReqHandler(id, menu, item){
	if(item == MENU_EXIT){
		menu_destroy(menu);
		showMenu(id);
		return PLUGIN_HANDLED;
	}
	new acc, call;
	new info[2];
	
	menu_item_getinfo(menu, item, acc, info, 1, _, _, call);
	switch(info[0]){
		case GROUP_PISTOLS: showLngMotd(id, "MOTD_REQ_PISTOLS");
		case GROUP_SMG: showLngMotd(id, "MOTD_REQ_SMG");
		case GROUP_SHOTGUNS: showLngMotd(id, "MOTD_REQ_SHOTGUNS");
		case GROUP_RIFELS: showLngMotd(id, "MOTD_REQ_RIFELS");
		case GROUP_SNIPERS: showLngMotd(id, "MOTD_REQ_SNIPERS");
		case GROUP_EXPLODE: showLngMotd(id, "MOTD_REQ_EXPLODE");
		case GROUP_KNIFE: showLngMotd(id, "MOTD_REQ_KNIFE");
		case GROUP_PARA: showLngMotd(id, "MOTD_REQ_PARA");
	}
	menu_destroy(menu);
	showLevelReqMenu(id);
	return PLUGIN_HANDLED;
}
//}
//{ BENEFITS
public showLevelBenefitsMenu(id){
	if(!isActive())
		return PLUGIN_CONTINUE;
		
	showWeaponGroupMenu(id, "WEAPON_LEVEL_BENEFITS", "levelBenefitsHandler");
	
	return PLUGIN_HANDLED;
}


public levelBenefitsHandler(id, menu, item) {
 	if(item == MENU_EXIT){
		menu_destroy(menu);
		return PLUGIN_HANDLED;
	}
	new info[2];
	static acc, call;
	new motd[128];
	
	menu_item_getinfo(menu, item, acc, info, 1, _, _, call);
	
	switch(info[0]){
		case GROUP_PISTOLS: formatex(motd, charsmax(motd), "%L", id, "MOTD_BENEFITS_PISTOLS");
		case GROUP_SMG: formatex(motd, charsmax(motd), "%L", id, "MOTD_BENEFITS_SMG");
		case GROUP_SHOTGUNS: formatex(motd, charsmax(motd), "%L", id, "MOTD_BENEFITS_SHOTGUNS");
		case GROUP_RIFELS: formatex(motd, charsmax(motd), "%L", id, "MOTD_BENEFITS_RIFELS");
		case GROUP_SNIPERS: formatex(motd, charsmax(motd), "%L", id, "MOTD_BENEFITS_SNIPERS");
		case GROUP_EXPLODE: formatex(motd, charsmax(motd), "%L", id, "MOTD_BENEFITS_EXPLODE");
		case GROUP_KNIFE: formatex(motd, charsmax(motd), "%L", id, "MOTD_BENEFITS_KNIFE");
		case GROUP_PARA: formatex(motd, charsmax(motd), "%L", id, "MOTD_BENEFITS_PARA");
	}
	if(motd[0]){
		show_motd(id, motd, PLUGIN);
	}
	
	menu_destroy(menu);
	showLevelBenefitsMenu(id);
	
	return PLUGIN_HANDLED;
 }
 

//}
//{ SETTINGS
enum _:MENU_SETTINGS_ITEM{
	MSI_NONE =0,
	MSI_DISP_RANK,
	MSI_DISP_WPN_LVL,
	MSI_DISP_AFTER_KILL,
	MSI_DISP_COORDINATE,
	MSI_SHOW_LVL_ON_KILL,
	MSI_SHOW_LVL_ON_WPN_CHANGE,
	MSI_SAVE,
	MSI_RESTORE
}
public showSettingsMenu(id){
	if(!isActive())
		return PLUGIN_CONTINUE;
		
	new title[64];
	formatex(title, charsmax(title), "\r%L", id, "MI_SETTINGS");
	
	new menu = menu_create(title, "settingsHandler");
	new info[2];
	new tmp = gPlayerSettings[id][SETTINGS_DISP_RANK];
	
	info[0] = MSI_DISP_RANK;
	formatex(title, charsmax(title), "%L [%L]", id, "MSI_DISP_RANK",id,  (tmp?"YES":"NO"));
	menu_additem(menu, title, info);
	
	if(tmp) {
		
		info[0] = MSI_DISP_WPN_LVL;
		formatex(title, charsmax(title), "%L [%L]", id, "MSI_DISP_WPN_LVL",id,  (gPlayerSettings[id][SETTINGS_DISP_WPN_LVL]?"YES":"NO"));
		menu_additem(menu, title, info);
	
		info[0] = MSI_DISP_AFTER_KILL;
		formatex(title, charsmax(title), "%L [%L]", id, "MSI_DISP_AFTER_KILL",id,  (gPlayerSettings[id][SETTINGS_DISP_AFTER_KILL]?"YES":"NO"));
		menu_additem(menu, title, info);
	
		new Float:tmpX = gPlayerSettings[id][SETTINGS_DISP_X];
		new strX[32];
		new Float:tmpY = gPlayerSettings[id][SETTINGS_DISP_Y];
		new strY[32];
		
		switch(tmpX){
			case -1.0: formatex(strX, charsmax(strX), "%L", id, "CENTER");
			default: float_to_str(tmpX, strX, charsmax(strX));
		}
		switch(tmpY){
			case -1.0: formatex(strY, charsmax(strY), "%L", id, "CENTER");
			default: float_to_str(tmpY, strY, charsmax(strY));
		}
		
		info[0] = MSI_DISP_COORDINATE;
		formatex(title, charsmax(title), "%L [X=%s, Y=%s]", id, "MSI_DISP_COORDINATE",strX, strY);
		menu_additem(menu, title, info);		
	}
	
	
	info[0] = MSI_SHOW_LVL_ON_KILL;
	formatex(title, charsmax(title), "%L [%L]", id, "MSI_SHOW_LVL_ON_KILL",id,  (gPlayerSettings[id][SETTINGS_SHOW_LVL_ON_KILL]?"YES":"NO"));
	menu_additem(menu, title, info);
	
	info[0] = MSI_SHOW_LVL_ON_WPN_CHANGE;
	formatex(title, charsmax(title), "%L [%L]", id, "MSI_SHOW_LVL_ON_WPN_CHANGE",id,  (gPlayerSettings[id][SETTINGS_SHOW_LVL_ON_WPN_CHANGE]?"YES":"NO"));
	menu_additem(menu, title, info);
	menu_display(id, menu);
	return PLUGIN_HANDLED;
}


public settingsHandler(id, menu, item){
	if(item == MENU_EXIT){
		menu_destroy(menu);
		return PLUGIN_HANDLED;
	}
	new acc, call;
	new info[2];
	new reshow = 0;
	menu_item_getinfo(menu, item, acc, info, 1, _, _, call);
	switch(info[0]){
		case MSI_DISP_RANK: {
			gPlayerSettings[id][SETTINGS_DISP_RANK] = (gPlayerSettings[id][SETTINGS_DISP_RANK]?0:1);
			reshow = 1;
		}
		case MSI_DISP_WPN_LVL :{
			gPlayerSettings[id][SETTINGS_DISP_WPN_LVL] = (gPlayerSettings[id][SETTINGS_DISP_WPN_LVL]?0:1);
			reshow = 1;
		}
		case MSI_DISP_AFTER_KILL:{
			new tmp = gPlayerSettings[id][SETTINGS_DISP_AFTER_KILL];
			gPlayerSettings[id][SETTINGS_DISP_AFTER_KILL] = (tmp?0:1);
			reshow = 1;
			if(tmp){ //was YES changed to NO
				if(task_exists(id + TASK_DISPLAY_RANK))
					remove_task(id + TASK_DISPLAY_RANK);
			} else {
				if(!task_exists(id + TASK_DISPLAY_RANK)){
					set_task(0.5, "showClientRank", id + TASK_DISPLAY_RANK, "", 0, "b");
				}
			}
		}
		case MSI_DISP_COORDINATE:{
			showCoordinateMenu(id);
		}		
		case MSI_SHOW_LVL_ON_KILL:{
			gPlayerSettings[id][SETTINGS_SHOW_LVL_ON_KILL] = (gPlayerSettings[id][SETTINGS_SHOW_LVL_ON_KILL]?0:1);
			reshow = 1;
		}
		case MSI_SHOW_LVL_ON_WPN_CHANGE:{
			gPlayerSettings[id][SETTINGS_SHOW_LVL_ON_WPN_CHANGE] = (gPlayerSettings[id][SETTINGS_SHOW_LVL_ON_WPN_CHANGE]?0:1);
			reshow = 1;
		}
		case MSI_SAVE:{
			savePlayerSettings(id);
			ColorChat(id, RED, "%L", id,  "SETTINGS_SAVED");
		}
		case MSI_RESTORE:{
			defaultPlayerSettings(id);
			ColorChat(id, RED, "%L", id,  "SETTINGS_DEFAULTED");
		}
	}
	menu_destroy(menu);
	if(reshow)
		showSettingsMenu(id);
	else {
		showMenu(id);
	}
	return PLUGIN_HANDLED;
}

enum _:COORD_MENU_ITEM {
	CMI_ADD_X =1,
	CMI_DEL_X,
	CMI_CENTER_X,
	CMI_ADD_Y,
	CMI_DEL_Y,
	CMI_CENTER_Y
}

public showClientRank(taskid){
	new id = taskid -TASK_DISPLAY_RANK;
	if(is_user_connected(id) && is_user_alive(id)){
		if(gPlayerSettings[id][SETTINGS_DISP_RANK] ){
			if(gPlayerSettings[id][SETTINGS_DISP_AFTER_KILL]){
				displayIfno(id, 5.0);
			} else {
				displayIfno(id, 1.0);
				if(!task_exists(taskid))
					set_task(0.5, "showClientRank", taskid, "", 0, "b");
			}
		}
	}
}

stock showCoordinateMenu(id){
	new title[64];
	formatex(title, charsmax(title), "\r%L", id, "MSI_DISP_Y");

	new menu = menu_create(title, "settingsCoordinateHandler");
	
	new info[2];
	
	info[0] = CMI_ADD_X;
	menu_additem(menu, "X +0.02", info);
	
	info[0] = CMI_DEL_X;
	menu_additem(menu, "X -0.02", info);
	
	info[0] = CMI_CENTER_X;
	formatex(title, charsmax(title), "X = %L", id, "CENTER");
	menu_additem(menu, title, info);
	
	info[0] = CMI_ADD_Y;
	menu_additem(menu, "Y +0.02", info);
	
	info[0] = CMI_DEL_Y;
	menu_additem(menu, "Y -0.02", info);
	
	info[0] = CMI_CENTER_Y;
	formatex(title, charsmax(title), "Y = %L", id, "CENTER");
	menu_additem(menu, title, info);
	
	menu_display(id, menu);
	return PLUGIN_HANDLED;
}

public settingsCoordinateHandler(id, menu, item){
	if(item == MENU_EXIT){
		menu_destroy(menu);
		showSettingsMenu(id);
		return PLUGIN_HANDLED;
	}
	new acc, call;
	new info[2];
	new Float:i;
	
	menu_item_getinfo(menu, item, acc, info, 1, _, _, call);
	switch(info[0]){
		case CMI_ADD_X: {
			i = gPlayerSettings[id][SETTINGS_DISP_X];
			gPlayerSettings[id][SETTINGS_DISP_X] =  _:floatclamp(i+0.02, 0.0, 1.0);
		}
		case CMI_DEL_X: {
			i = gPlayerSettings[id][SETTINGS_DISP_X];
			gPlayerSettings[id][SETTINGS_DISP_X] =  _:floatclamp(i-0.02, 0.0, 1.0);
		}
		case CMI_CENTER_X: {
			 gPlayerSettings[id][SETTINGS_DISP_X] =  _:-1.0;
		}
		
		case CMI_ADD_Y: {
			i = gPlayerSettings[id][SETTINGS_DISP_Y];
			gPlayerSettings[id][SETTINGS_DISP_Y] =  _:floatclamp(i+0.02, 0.0, 1.0);
		}
		case CMI_DEL_Y: {
			i = gPlayerSettings[id][SETTINGS_DISP_Y];
			gPlayerSettings[id][SETTINGS_DISP_Y] =  _:floatclamp(i-0.02, 0.0, 1.0);
		}
		case CMI_CENTER_Y: {
			 gPlayerSettings[id][SETTINGS_DISP_Y] =  _:-1.0;
		}
	}
	menu_destroy(menu);
	displayIfno(id , 5.0);
	showCoordinateMenu(id);
	return PLUGIN_HANDLED;
}


//} SETTINGS
















//{ PLAYER STATS
public showPlayerStats(id, player){
	new motd[1530];
	new name[MAX_KEY_LEN];
	get_user_name(player, name, MAX_KEY_LEN-1);
	
	formatex(motd, charsmax(motd)),
		"<html><head><title>%s</title><meta http-equiv=^"Content-Type^" content=^"text/html; charset=UTF-8^">\
<link rel=^"stylesheet^" type=^"text/css^" href=^"%L^" /></head><body><h1>%s</h1><h2>%s %L</h2>",PLUGIN, id, "CSS_FILE", PLUGIN, name, id, "STATISTICS");
	format(motd, charsmax(motd)), "%s"
	format(motd, charsmax(motd)),"%s</body></html>", motd);
}
//}
